﻿using System;
using System.Linq.Expressions;

namespace Web7.Ioc
{
    /// <summary>
    /// 注册依赖管理
    /// </summary>
    /// <typeparam name="T">该组件的类型</typeparam>
    public interface IDependencyRegistrar<T>
    {
        /// <summary>
        /// 配置该组件将提供的服务
        /// </summary>
        /// <param name="type">指定该组件的类型</param>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> KnownAs(Type type);
        /// <summary>
        /// 配置该组件将提供的服务
        /// </summary>
        /// <typeparam name="TContract">指定该组件的类型</typeparam>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> KnownAs<TContract>();
        /// <summary>
        /// 提供一个文本的名称，可以用来检索组件。
        /// </summary>
        /// <typeparam name="TContract">注册组件的类型</typeparam>
        /// <param name="name">该组件的名称</param>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> Named<TContract>(string name);
        /// <summary>
        /// 提供一个文本的名称，可以用来检索组件。
        /// </summary>
        /// <param name="name">该组件的名称</param>
        /// <param name="type">注册组件的类型</param>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> Named(string name, Type type);
        /// <summary>
        /// 依赖注入实例的区域
        /// </summary>
        IScopeManager<T> ScopedAs { get; }
        /// <summary>
        /// 注册组件最具体（原始）的类型
        /// </summary>
        Type RawType { get; }
        /// <summary>
        /// 一旦注册然后回调
        /// </summary>
        /// <param name="action">回调函数(含有依赖注入解析方案)</param>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> OnActivated(Action<IResolutionContext, T> action);
       
        
        IDependencyRegistrar<T> WithResolvedParam<TParam>(Func<IResolutionContext, TParam> callback);

        IDependencyRegistrar<T> WithMetadata<TMetadata, TProperty>(
            Expression<Func<TMetadata, TProperty>> propertyAccessor, TProperty value);
        /// <summary>
        /// 根据设定明确的构造函数名来注册
        /// </summary>
        /// <param name="paramterName">参数名</param>
        /// <param name="value">参数值</param>
        /// <returns>注册组件者进一步配置</returns>
        IDependencyRegistrar<T> WithNamedParam(string paramterName, object value);
    }
}
